package net.asrsmid.sample.queryeditor;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.olap4j.CellSet;

import net.asrsmid.config.AsRsAuthenticator;
import net.asrsmid.config.AsRsConfig;
import net.asrsmid.config.AsRsConfigLoader;
import net.asrsmid.connection.AsRsApplicationPool;
import net.asrsmid.connection.AsRsApplicationPoolManager;
import net.asrsmid.connection.as.AsOlapConnection;
import net.asrsmid.invoker.RsWebserviceInvoker;
import net.asrsmid.invoker.as.Table;
import net.asrsmid.invoker.as.TableFactory;
import net.asrsmid.invoker.as.TableUtility;

/**
 * Servlet implementation class QueryEditorServlet
 */
public class QueryEditorServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
     
	private static final String AS_APP_ID = "QUERY_EDITOR";
	private static final String RS_APP_ID = "QUERY_EDITOR";
	
	private AsRsApplicationPool pool;
	
    public void init() throws ServletException {
		String configFilePath = getServletContext().getRealPath("WEB-INF/asrsmidsample-conf.xml");
		AsRsConfig asrsConfig = AsRsConfigLoader.loadAsRsConfig(configFilePath);
		pool = AsRsApplicationPoolManager.getApplicationPool(asrsConfig);
    }
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public QueryEditorServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		handleQuery(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		handleQuery(request, response);
	}

	private void handleQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String qType = request.getParameter("type");
		String qAsRequest = request.getParameter("request");
		String qAsFunc = request.getParameter("asFunc");
		String qAsPrecision = request.getParameter("precision");
		String qRsPath = request.getParameter("path");
		String qRsFunc = request.getParameter("rsFunc");
		String qRsParam1 = request.getParameter("param1");
		String qRsParam2 = request.getParameter("param2");
		String qRsParam3 = request.getParameter("param3");
		String qRsParam4 = request.getParameter("param4");
		String qRsParam5 = request.getParameter("param5");
		List<String> qRsParams = new ArrayList<String>();
		if (qRsParam1 != null && !qRsParam1.equals("") && qRsParam1.indexOf("=") != -1 && qRsParam1.indexOf("=") < qRsParam1.length() - 1)
			qRsParams.add(qRsParam1);
		if (qRsParam2 != null && !qRsParam2.equals("") && qRsParam2.indexOf("=") != -1 && qRsParam2.indexOf("=") < qRsParam2.length() - 1)
			qRsParams.add(qRsParam2);
		if (qRsParam3 != null && !qRsParam3.equals("") && qRsParam3.indexOf("=") != -1 && qRsParam3.indexOf("=") < qRsParam3.length() - 1)
			qRsParams.add(qRsParam3);
		if (qRsParam4 != null && !qRsParam4.equals("") && qRsParam4.indexOf("=") != -1 && qRsParam4.indexOf("=") < qRsParam4.length() - 1)
			qRsParams.add(qRsParam4);
		if (qRsParam5 != null && !qRsParam5.equals("") && qRsParam5.indexOf("=") != -1 && qRsParam5.indexOf("=") < qRsParam5.length() - 1)
			qRsParams.add(qRsParam5);
		
		OutputStream os = response.getOutputStream();

		if ("as".equalsIgnoreCase(qType)) {
			Table result = null;
			try {
				AsOlapConnection conn = null;
				try {
					int precision = 2;
					try {
						precision = Integer.parseInt(qAsPrecision);
					} catch(Exception ce) {
					}
					conn = pool.getAsOlapConnection(AS_APP_ID);
					CellSet cellSet = conn.executeMdxQuery(qAsRequest);
					result = TableFactory.build(cellSet, precision);
				} catch (Throwable t) {
					t.printStackTrace();
				} finally {
				    try {
				        if (conn != null) conn.release();
		            } catch (Exception e) {
		                e.printStackTrace();
		            }
				}
				
				if ("array".equalsIgnoreCase(qAsFunc)) {
					os.write(TableUtility.toJsArrayString(result).getBytes());
				} else if ("csv".equalsIgnoreCase(qAsFunc)) {
					response.setContentType("application/octet-stream");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AsRsMidSample.csv\"");
					os.write(TableUtility.toCsv(result));
				} else if ("xsl".equalsIgnoreCase(qAsFunc)) {
					response.setContentType("application/vnd.ms-excel");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AsRsMidSample.xls\"");
					os.write(TableUtility.toExcel(result));
				} else if ("xml".equalsIgnoreCase(qAsFunc)) {
					response.setContentType("application/octet-stream");
		            response.addHeader("Content-Disposition", "attachment;filename=\"AsRsMidSample.xml\"");
					os.write(TableUtility.toXml(result));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if ("rs".equalsIgnoreCase(qType)) {
			Map<String, String> params = new HashMap<String, String>();
			for (String param : qRsParams) {
				int idx = param.indexOf("=");
				params.put(param.substring(0, idx), param.substring(idx + 1));
			}
			
			AsRsAuthenticator auth = new AsRsAuthenticator(
					pool.getConfig().getRsAuthMode(RS_APP_ID), 
					pool.getConfig().getRsDefaultUserName(RS_APP_ID),
					pool.getConfig().getRsDefaultUserPassword(RS_APP_ID));
			
			String reportPath = pool.getConfig().getReport(RS_APP_ID, qRsPath).getServerPath();
			
			RsWebserviceInvoker rsInvoker = new RsWebserviceInvoker(pool.getRsWebserviceProxy(AS_APP_ID));
			byte[] result = rsInvoker.getReport(reportPath, params, qRsFunc, null, auth);

			 if ("excel".equalsIgnoreCase(qRsFunc)) {
				response.setContentType("application/vnd.ms-excel");
	            response.addHeader("Content-Disposition", "attachment;filename=\"AsRsMidSample.xls\"");
				os.write(result);
			} else {
				os.write(result);
			}
		}

		os.flush();
		os.close();
	}
}
